#pragma once
#ifndef xVector_h__
#define xVector_h__

#include "../inc/skyType.h"
//
//namespace NLib
//{
//	template <typename T, i32 N>
//	class xVector
//	{
//	public:
//		xVector() {};
//		xVector( const xVector& v)
//		{
//			*this = v;
//		}
//
//		xVector(const T d1,...)
//		{
//			i32 i = 1;
//			this->data_[0] = d1;
//			va_list va;
//			va_start(va, d1);
//			while(i < N)
//			{
//				data_[i] = (T) va_arg(va, const T); 
//				i++;
//			}
//			va_end(va);
//		}
//		// vector operators
//		//xVector& operator += ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] += rhs[i];
//		//}
//		//xVector& operator -= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] -= rhs[i];
//		//	return *this;
//		//}
//		//xVector& operator *= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] *= rhs[i];
//		//	return *this;
//		//}
//		//xVector& operator /= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] /= rhs[i];
//		//	return *this;
//		//}
//
//		////factor operators
//		//xVector& operator += ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] += v;
//		//	return *this;
//		//}
//		//xVector& operator -= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] -= v;
//		//	return *this;
//		//}
//		//xVector& operator *= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] *= v;
//		//	return *this;
//		//}
//		//xVector& operator /= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] /= v;
//		//}
//
//		////
//		//xVector  operator + ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] += rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator - ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] -= rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator * ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] *= rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator / ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] /= rhs.data_[i];
//		//	return temp;
//		//}
//		//// binary operators
//		//xVector operator + ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] + v;
//		//	return temp;
//		//}
//		//xVector operator - ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] - v;
//		//	return temp;
//		//}
//		//xVector operator * ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] * v;
//		//	return temp;
//		//}
//		//xVector operator / ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] / v;
//		//	return temp;
//		//}
//		////friend function
//		//friend xVector operator * ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v * rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//		//friend xVector operator / ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v / rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator + ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v + rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator - ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v - rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator - ( const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = -rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//compare
//		Bool operator == ( const xVector& rhs) const
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//			{
//				if( data_[i] != rhs[i])
//					return vFalse;
//			}
//			return vTrue;
//		}
//
//		Bool operator != ( const xVector& rhs) const
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//			{
//				if( data_[0] != rhs[0])
//					return vTrue;
//			}
//			return vFalse;
//		}
//
//		Void operator =  ( const T& v)
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//				data_[i] = v;
//		}
//		T&	operator [] (int i)
//		{
//			xAssert(i < N);
//			return data_[i];
//		}
//		//dist
//	public:
//		typedef T value_type;
//		const static u32 value_size = N;
//		
//
//		typedef typename T::value_type sub_value_type;
//		typedef typename value_type row_value_type;
//		typedef typename xVector<typename T::value_type,value_size> col_value_type;
//
//		const static u32 col_value_size = row_value_type::value_size;
//		const static u32 row_value_size = col_value_type::value_size;
//
//		const static u32 atom_type_depth = T::atom_type_depth + 1;
//		typedef typename T::atom_value_type atom_value_type;
//
////		template <i32 N>
////		struct type_at_depth
////		{
////			typedef typename xVector::type_at_depth<N-1>::value_type value_type;
////		};
////
////		template <>
////		struct type_at_depth<0>
////		{
////			typedef T value_type;
////		};
//	private:
//		T data_[N];
//
//	};
//
//
//	template <i32 N>
//	class xVector<i32,N>
//	{
//		typedef i32 T;
//	public:
//		xVector() {};
//		xVector( const xVector& v)
//		{
//			*this = v;
//		}
//
//		xVector(const T d1,...)
//		{
//			i32 i = 1;
//			this->data_[0] = d1;
//			va_list va;
//			va_start(va, d1);
//			while(i < N)
//			{
//				data_[i] = (T) va_arg(va, const T); 
//				i++;
//			}
//			va_end(va);
//		}
//		// vector operators
//		//xVector& operator += ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] += rhs[i];
//		//}
//		//xVector& operator -= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] -= rhs[i];
//		//	return *this;
//		//}
//		//xVector& operator *= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] *= rhs[i];
//		//	return *this;
//		//}
//		//xVector& operator /= ( const xVector& rhs)
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] /= rhs[i];
//		//	return *this;
//		//}
//
//		////factor operators
//		//xVector& operator += ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] += v;
//		//	return *this;
//		//}
//		//xVector& operator -= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] -= v;
//		//	return *this;
//		//}
//		//xVector& operator *= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] *= v;
//		//	return *this;
//		//}
//		//xVector& operator /= ( const T& v )
//		//{
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		data_[i] /= v;
//		//}
//
//		////
//		//xVector  operator + ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] += rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator - ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] -= rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator * ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] *= rhs.data_[i];
//		//	return temp;
//		//}
//		//xVector  operator / ( const xVector& rhs )
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp.data_[i] = data_[i] /= rhs.data_[i];
//		//	return temp;
//		//}
//		//// binary operators
//		//xVector operator + ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] + v;
//		//	return temp;
//		//}
//		//xVector operator - ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] - v;
//		//	return temp;
//		//}
//		//xVector operator * ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] * v;
//		//	return temp;
//		//}
//		//xVector operator / ( const T& v) const
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//		temp[i] = data_[i] / v;
//		//	return temp;
//		//}
//		////friend function
//		//friend xVector operator * ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v * rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//		//friend xVector operator / ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v / rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator + ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v + rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator - ( const T v, const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = v - rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//friend xVector operator - ( const xVector& rhs) 
//		//{
//		//	xVector temp;
//		//	for(i32 i = N - 1; i >= 0; i --)
//		//	{
//		//		temp.data_[i] = -rhs.data_[i];
//		//	}
//		//	return temp;
//		//}
//
//		//compare
//		Bool operator == ( const xVector& rhs) const
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//			{
//				if( data_[i] != rhs[i])
//					return vFalse;
//			}
//			return vTrue;
//		}
//
//		Bool operator != ( const xVector& rhs) const
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//			{
//				if( data_[0] != rhs[0])
//					return vTrue;
//			}
//			return vFalse;
//		}
//
//		Void operator =  ( const T& v)
//		{
//			for(i32 i = N - 1; i >= 0; i --)
//				data_[i] = v;
//		}
//		T&	operator [] (int i)
//		{
//			xAssert(i < N);
//			return data_[i];
//		}
//		//dist
//	public:
//		const static u32 value_size = N;
//		const static u32 row_value_size = 1;
//		const static u32 col_value_size = N;
//
//		const static u32 atom_type_depth = 0;
//		typedef T value_type;
//		typedef T (col_value_type)[0];
//		typedef T atom_value_type;
//	private:
//		T data_[N];
//
//	};
//
//	//template <typename T,i32 N>
//	//T* xVectorDot(T* out,const xVector<T,N>* v1,const xVector<T,N>* v2)
//	//{
//	//	T v = (*(xVector<T,N>*)v1)[0] * (*(xVector<T,N>*)v2)[0];
//	//	for(i32 i = N - 1; i > 0; i --)
//	//	{
//	//		v += (*(xVector<T,N>*)v1)[i] * (*(xVector<T,N>*)v2)[i];
//	//	}
//	//	*out = v;
//	//	return out;
//	//}
//
//	//template <typename T>
//	//class xVector<T,1>
//	//{
//	//public:
//	//	xVector() {};
//	//	xVector( const xVector& v)
//	//	{
//	//		this->x = v.x;
//	//	}
//	//	xVector( const T x)
//	//	{
//	//		this->x = x;
//	//	}
//
//	//	// assignment operators
//	//	xVector& operator += ( const xVector& rhs)
//	//	{
//	//		x += rhs.x;
//	//		return *this;
//	//	}
//	//	xVector& operator -= ( const xVector& rhs)
//	//	{
//	//		x -= rhs.x;
//	//		return *this;
//	//	}
//	//	xVector& operator *= ( T v )
//	//	{
//	//		x *= v;
//	//		return *this;
//	//	}
//	//	xVector& operator /= ( T v )
//	//	{
//	//		x /= v;
//	//		return *this;
//	//	}
//
//	//	// binary operators
//	//	xVector operator + ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x + rhs.x;
//	//		return temp;
//	//	}
//	//	xVector operator - ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x - rhs.x;
//	//		return temp;
//	//	}
//	//	xVector operator * ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x * v;
//	//		return temp;
//	//	}
//	//	xVector operator / ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x / v;
//	//		return temp;
//	//	}
//
//	//	friend xVector operator * ( T v, const xVector& rhs)
//	//	{
//	//		xVector temp;
//	//		temp.x = rhs.x / v;
//	//		return temp;
//	//	}
//
//	//	Bool operator == ( const xVector& rhs) const
//	//	{
//	//		if( x == rhs.x)
//	//			return vTrue;
//	//		return vFalse;
//	//	}
//
//	//	Bool operator != ( const xVector& rhs) const
//	//	{
//	//		if( x == rhs.x)
//	//			return vFalse;
//	//		return vTrue;
//	//	}
//
//	//	T&	operator [] (int i)
//	//	{
//	//		xAssert(i == 0);
//	//		return x;
//	//	}
//	//public:
//	//	const static u32 value_size = 1;
//	//	typedef T value_type;
//	//public:
//	//	T    x;
//	//};
//
//	//template <typename T>
//	//class xVector<T,2>
//	//{
//	//public:
//	//	xVector() {};
//	//	xVector( const xVector& v)
//	//	{
//	//		*this = v;
//	//	}
//
//	//	xVector( T x, T y)
//	//	{
//	//		this->x = x;
//	//		this->y = y;
//	//	}
//
//	//	// assignment operators
//	//	xVector& operator += ( const xVector& rhs)
//	//	{
//	//		data_[0] += rhs[0];
//	//		data_[1] += rhs[1];
//	//		return *this;
//	//	}
//	//	xVector& operator -= ( const xVector& rhs)
//	//	{
//	//		data_[0] -= rhs[0];
//	//		data_[1] -= rhs[1];
//	//		return *this;
//	//	}
//	//	xVector& operator *= ( T v )
//	//	{
//	//		data_[0] *= v;
//	//		data_[1] *= v;
//	//		return *this;
//	//	}
//	//	xVector& operator /= ( T v )
//	//	{
//	//		data_[0] /= v;
//	//		data_[1] /= v;
//	//		return *this;
//	//	}
//
//	//	// unary operators
//	//	xVector operator + () const;
//	//	xVector operator - () const;
//
//	//	// binary operators
//	//	xVector operator + ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] + rhs[0];
//	//		temp[1] = data_[1] + rhs[1];
//	//		return temp;
//	//	}
//	//	xVector operator - ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] - rhs[0];
//	//		temp[1] = data_[1] - rhs[1];
//	//		return temp;
//	//	}
//	//	xVector operator * ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] * v;
//	//		temp[1] = data_[1] * v;
//	//		return temp;
//	//	}
//	//	xVector operator / ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] / v;
//	//		temp[1] = data_[1] / v;
//	//		return temp;
//	//	}
//
//	//	friend xVector operator * ( T v, const xVector& rhs)
//	//	{
//	//		xVector temp;
//	//		temp[0] = rhs[0] / v;
//	//		temp[1] = rhs[1] / v;
//	//		return temp;
//	//	}
//
//	//	Bool operator == ( const xVector& rhs) const
//	//	{
//	//		if( data_[0] == rhs[0] &&
//	//			data_[1] == rhs[1] )
//	//			return vTrue;
//	//		return vFalse;
//	//	}
//
//	//	Bool operator != ( const xVector& rhs) const
//	//	{
//	//		if( data_[0] == rhs[0] &&
//	//			data_[1] == rhs[1])
//	//			return vFalse;
//	//		return vTrue;
//	//	}
//
//	//	T&	operator [] (int i)
//	//	{
//	//		switch(i)
//	//		{
//	//		case 0:
//	//			return x;
//	//			break;
//	//		case 1:
//	//			return y;
//	//			break;
//	//		}
//	//		xAssert(vFalse);
//	//		return x;
//	//	}
//	//public:
//	//	static Float dot(xVector* v1,xVector* v2)
//	//	{
//	//		float f = v1->x * v2->x;
//	//		f += v1->y * v2->y;
//	//		return f;
//	//	}
//	//	static Float distance(xVector* v)
//	//	{
//	//		return sqrtf(dot(v,v));
//	//	}
//	//public:
//	//	const static u32 value_size = 2;
//	//	typedef T value_type;
//	//public:
//	//	T    x,y;
//	//};
//
//	//template <typename T>
//	//class xVector<T,3>
//	//{
//
//	//public:
//	//	xVector() {};
//	//	xVector( const T v )
//	//	{
//	//		this->x = v;
//	//		this->y = v;
//	//		this->z = v;
//	//	}
//
//	//	xVector( const xVector& v)
//	//	{
//	//		*this = v;
//	//	}
//	//	xVector( T x, T y, T z )
//	//	{
//	//		this->x = x;
//	//		this->y = y;
//	//		this->z = z;
//	//	}
//
//	//	operator const T* () const;
//
//	//	// assignment operators
//	//	xVector& operator += ( const xVector& rhs)
//	//	{
//	//		x += rhs.x;
//	//		y += rhs.y;
//	//		z += rhs.z;
//	//		return *this;
//	//	}
//	//	xVector& operator -= ( const xVector& rhs)
//	//	{
//	//		x -= rhs.x;
//	//		y -= rhs.y;
//	//		z -= rhs.z;
//	//		return *this;
//	//	}
//	//	xVector& operator *= ( T v )
//	//	{
//	//		x *= v;
//	//		y *= v;
//	//		z *= v;
//	//		return *this;
//	//	}
//	//	xVector& operator /= ( T v )
//	//	{
//	//		x /= v;
//	//		y /= v;
//	//		z /= v;
//	//		return *this;
//	//	}
//
//
//	//	// binary operators
//	//	xVector operator + ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x + rhs.x;
//	//		temp.y = y + rhs.y;
//	//		temp.z = z + rhs.z;
//	//		return temp;
//	//	}
//	//	xVector operator - ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x - rhs.x;
//	//		temp.y = y - rhs.y;
//	//		temp.z = z - rhs.z;
//	//		return temp;
//	//	}
//	//	xVector operator * ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp.x = x * v;
//	//		temp.y = y * v;
//	//		temp.z = z * v;
//	//		return temp;
//	//	}
//	//	xVector operator / ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp.x = rhs.x / v;
//	//		temp.y = rhs.y / v;
//	//		temp.z = rhs.z / v;
//	//		return temp;
//	//	}
//
//	//	friend xVector operator * ( T v, const xVector& rhs)
//	//	{
//	//		xVector temp;
//	//		temp.x = rhs.x * v;
//	//		temp.y = rhs.y * v;
//	//		temp.z = rhs.z * v;
//	//		return temp;
//	//	}
//
//	//	Bool operator == ( const xVector& rhs) const
//	//	{
//	//		if( x == rhs.x &&
//	//			y == rhs.y &&
//	//			z == rhs.z)
//	//			return vTrue;
//	//		return vFalse;
//	//	}
//
//	//	Bool operator != ( const xVector& rhs) const
//	//	{
//	//		if( x == rhs.x &&
//	//			y == rhs.y &&
//	//			z == rhs.z)
//	//			return vFalse;
//	//		return vTrue;
//	//	}
//	//	
//	//	T&	operator [] (i32 i)
//	//	{
//	//		switch(i)
//	//		{
//	//		case 0:
//	//			return x;
//	//			break;
//	//		case 1:
//	//			return y;
//	//			break;;
//	//		case 2:
//	//			return z;
//	//			break;
//	//		}
//	//		return x;
//	//	}
//	//public:
//	//	const static u32 value_size = 3;
//	//	typedef T value_type;
//	//public:
//	//	T    x,y,z;
//	//};
//
//	//template <typename T>
//	//class xVector<T,4>
//	//{
//
//	//public:
//	//	xVector() {};
//	//	xVector( const T v )
//	//	{
//	//		this->x = v;
//	//		this->y = v;
//	//		this->z = v;
//	//		this->w = v;
//	//	}
//
//	//	xVector( const xVector& v)
//	//	{
//	//		*this = v;
//	//	}
//	//	xVector( T x, T y, T z,T w)
//	//	{
//	//		this->x = x;
//	//		this->y = y;
//	//		this->z = z;
//	//		this->w = w;
//	//	}
//
//	//	operator const T* () const;
//
//	//	// assignment operators
//	//	xVector& operator += ( const xVector& rhs)
//	//	{
//	//		data_[0] += rhs[0];
//	//		data_[1] += rhs[1];
//	//		data_[2] += rhs[2];
//	//		data_[3] += rhs[3];
//	//		return *this;
//	//	}
//	//	xVector& operator -= ( const xVector& rhs)
//	//	{
//	//		data_[0] -= rhs[0];
//	//		data_[1] -= rhs[1];
//	//		data_[2] -= rhs[2];
//	//		data_[3] -= rhs[3];
//	//		return *this;
//	//	}
//	//	xVector& operator *= ( T v )
//	//	{
//	//		data_[0] *= v;
//	//		data_[1] *= v;
//	//		data_[2] *= v;
//	//		data_[3] *= v;
//	//		return *this;
//	//	}
//	//	xVector& operator /= ( T v )
//	//	{
//	//		data_[0] /= v;
//	//		data_[1] /= v;
//	//		data_[2] /= v;
//	//		data_[3] /= v;
//	//		return *this;
//	//	}
//
//	//	// unary operators
//	//	xVector operator + () const;
//	//	xVector operator - () const;
//
//	//	// binary operators
//	//	xVector operator + ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] + rhs[0];
//	//		temp[1] = data_[1] + rhs[1];
//	//		temp[2] = data_[2] + rhs[2];
//	//		temp[3] = data_[3] + rhs[3];
//	//		return temp;
//	//	}
//	//	xVector operator - ( const T& rhs) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] - rhs[0];
//	//		temp[1] = data_[1] - rhs[1];
//	//		temp[2] = data_[2] - rhs[2];
//	//		temp[3] = data_[3] - rhs[3];
//	//		return temp;
//	//	}
//	//	xVector operator * ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] * v;
//	//		temp[1] = data_[1] * v;
//	//		temp[2] = data_[2] * v;
//	//		temp[3] = data_[3] * v;
//	//		return temp;
//	//	}
//	//	xVector operator / ( T v ) const
//	//	{
//	//		xVector temp;
//	//		temp[0] = data_[0] / v;
//	//		temp[1] = data_[1] / v;
//	//		temp[2] = data_[2] / v;
//	//		temp[3] = data_[3] / v;
//	//		return temp;
//	//	}
//
//	//	friend xVector operator * ( T v, const xVector& rhs)
//	//	{
//	//		xVector temp;
//	//		temp[0] = rhs[0] / v;
//	//		temp[1] = rhs[1] / v;
//	//		temp[2] = rhs[2] / v;
//	//		temp[3] = rhs[3] / v;
//	//		return temp;
//	//	}
//
//	//	Bool operator == ( const xVector& rhs) const
//	//	{
//	//		if( data_[0] == rhs[0] &&
//	//			data_[1] == rhs[1] &&
//	//			data_[2] == rhs[2] &&
//	//			data_[3] == rhs[3])
//	//			return vTrue;
//	//		return vFalse;
//	//	}
//
//	//	Bool operator != ( const xVector& rhs) const
//	//	{
//	//		if( data_[0] == rhs[0] &&
//	//			data_[1] == rhs[1] &&
//	//			data_[2] == rhs[2] &&
//	//			data_[3] == rhs[3])
//	//			return vFalse;
//	//		return vTrue;
//	//	}
//
//	//	T&	operator [] (int i)
//	//	{
//	//		switch(i)
//	//		{
//	//		case 0:
//	//			return x;
//	//			break;
//	//		case 1:
//	//			return y;
//	//			break;;
//	//		case 2:
//	//			return z;
//	//			break;
//	//		case 3:
//	//			return w;
//	//			break;
//	//		}
//	//		xAssert(vFalse);
//	//		return x;
//	//	}
//	//public:
//	//	const static u32 value_size = 4;
//	//	typedef T value_type;
//	//public:
//	//	T    x,y,z,w;
//	//};
//
//	//typedef xVector<i32,1>		TInt1;
//	//typedef xVector<i32,2>		TInt2;
//	//typedef xVector<i32,3>		TInt3;
//	//typedef xVector<i32,4>		TInt4;
//	//typedef xVector<TInt4,4>	TInt4x4;
//	//typedef xVector<TInt4x4,4>	TInt4x4x4;
//	//
//#define VECTOR_DEF1(type,size)			typedef xVector<type,size>									i32##size
//#define VECTOR_DEF2(type,row,col)		typedef xVector<xVector<type,col>,row>						i32##row##x##col
//#define VECTOR_DEF3(type,row,col,size)	typedef xVector<xVector<xVector<type,col>,size>,row>		i32##row##x##col##x##size
//
//	VECTOR_DEF1(i32,1);
//	VECTOR_DEF1(i32,2);
//	VECTOR_DEF1(i32,3);
//	VECTOR_DEF1(i32,4);
//	VECTOR_DEF2(i32,4,4);
//}
//
////#include <iostream>
//
//namespace NLib
//{
//	namespace NInternal
//	{
//		struct vector_math_helper
//		{
//			// A = c + B
//			template <typename TC,typename T,typename TSUB>
//			static T& coff_add(T& out,const TC coff,const T& in,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::coff_add(&((typename T::value_type&)(out)[i]),coff,in[i],in[i][0]);
//				}
//				return out;
//			}
//			template <typename TC,typename T>
//			static T& coff_add(T& out,TC coff,const T& in,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = coff + ((T&)in)[i];
//				}
//				return out;
//			}
//			// A = B + C
//			template <typename T,typename TSUB>
//			static T& ele_add(T& out,const T& t1,const T& t2,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_add((typename T::value_type&)(out[i]),(typename T::value_type&)(((T&)t1)[i]),(typename T::value_type&)(((T&)t2)[i]),((T::value_type&)((T&)t1)[i])[0]);
//				}
//				return out;
//			}
//			template <typename T>
//			static T& ele_add(T& out,const T& t1,const T& t2,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = ele_add(out[i],((T&)t1)[i],((T&)t2)[i]);
//				}
//				return out;
//			}
//			static i32& ele_add(i32& out,const i32& t1,const i32& t2)
//			{
//				out = t1 + t2;
//				return out;
//			}
//			// A = c - B
//			template <typename TC,typename T,typename TSUB>
//			static T& coff_sub(T& out,const TC coff,const T& in,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::coff_sub(&((typename T::value_type&)(out)[i]),coff,in[i],in[i][0]);
//				}
//				return out;
//			}
//			template <typename TC,typename T>
//			static T& coff_sub(T& out,TC coff,const T& in,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = coff - ((T&)in)[i];
//				}
//				return out;
//			}
//			//A = B - C
//			template <typename T,typename TSUB>
//			static T& ele_sub(T& out,const T& t1,const T& t2,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_sub((typename T::value_type&)(out[i]),(typename T::value_type&)(((T&)t1)[i]),(typename T::value_type&)(((T&)t2)[i]),((T::value_type&)((T&)t1)[i])[0]);
//				}
//				return out;
//			}
//			template <typename T>
//			static T& ele_sub(T& out,const T& t1,const T& t2,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = ((T&)t1)[i] - ((T&)t2)[i];
//				}
//				return out;
//			}
//			// A = c * B
//			template <typename TC,typename T,typename TSUB>
//			static T& coff_mul(T& out,const TC coff,const T& in,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::coff_mul(((out)[i]),coff,(((T&)in)[i]),((T::value_type&)((T&)in)[i])[0]);
//				}
//				return out;
//			}
//			template <typename TC,typename T>
//			static T& coff_mul(T& out,TC coff,const T& in,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = coff * ((T&)in)[i];
//				}
//				return out;
//			}
//			// A = c / B
//			template <typename TC,typename T,typename TSUB>
//			static T& coff_div(T& out,const TC coff,const T& in,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::coff_div(&((typename T::value_type&)(out)[i]),coff,in[i],in[i][0]);
//				}
//				return out;
//			}
//			template <typename TC,typename T>
//			static T& coff_div(T& out,TC coff,const T& in,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					if(((T&)in)[i] == 0)
//						out[i] = vMaxInt;
//					else
//						out[i] = coff / ((T&)in)[i];
//				}
//				return out;
//			}
//			// A = B * C
//			template <typename T,typename TSUB>
//			static T& ele_mul(T& out,const T& t1,const T& t2,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_mul((typename T::value_type&)(out[i]),(typename T::value_type&)(((T&)t1)[i]),(typename T::value_type&)(((T&)t2)[i]),((T::value_type&)((T&)t1)[i])[0]);
//				}
//				return out;
//			}
//			template <typename T>
//			static T& ele_mul(T& out,const T& t1,const T& t2,const i32& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out[i] = ((T&)t1)[i] * ((T&)t2)[i];
//				}
//				return out;
//			}
//			// A = B dot C
//			template <typename T,typename TSUB>
//			static T& dot_mul(T& out,const T& t1,const T& t2,const TSUB& sub)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_mul(&((typename T::value_type&)(out)[i]),t1,t2,t1[i][0]);
//				}
//				return out;
//			}
//			template <typename T>
//			static i32& dot_mul(i32& out,const T& t1,const T& t2,const i32& sub)
//			{
//				out = 0;
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					out  += ((T&)t1)[i] * ((T&)t2)[i];
//				}
//				return out;
//			}
//			template <typename T>
//			static T& dot_mul(T& out,const T& t1,const T& t2)
//			{
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_mul(&((typename T::value_type&)(out)[i]),t1,t2,t1[i][0]);
//				}
//				return out;
//			}
//			static i32& dot_mul(i32& out,const i32& t1,const i32& t2)
//			{
//				out = t1 * t2;
//				return out;
//			}
//			template <typename T>
//			static T& dot_mul_add(T& out,const T& t1,const T& t2)
//			{
//				typename T::value_type& tmp;
//				for(i32 i = 0; i < T::value_size; i ++)
//				{
//					vector_math_helper::ele_add(((typename T::value_type&)(out)[i]),tmp,vector_math_helper::ele_mul_mul(tmp,t1,t2,t1[i][0]));
//				}
//				return out;
//			}
//			static i32& dot_mul_add(i32& out,const i32& t1,const i32& t2)
//			{
//				out += t1 * t2;
//				return out;
//			}
//		};
//
//		
//		//Void print_helper(const i32& t)
//		//{
//		//	std::cout<<"\t";
//		//	std::cout<<t;
//		//	std::cout<<std::endl;
//		//}
//		//template <typename T>
//		//Void print_helper(const T& t)
//		//{
//		//	for(i32 i = 0; i < T::value_size; i ++)
//		//	{
//		//		std::cout<<"\t";
//		//		print_sub_helper(((T&)t)[i]);
//		//	}
//		//	std::cout<<std::endl;
//		//}
//		//template <typename T>
//		/*Void print_sub_helper(const T& t)
//		{
//			for(i32 i = 0; i < T::value_size; i ++)
//			{
//				print_sub_helper(((T&)t)[i]);
//				std::cout<<"\t";
//			}
//			std::cout<<std::endl;
//		}
//		template <>
//		Void print_sub_helper(const i32& t)
//		{
//			std::cout<<t<<"\t";
//		};*/
//	}
//	//out = v1 + v2
//	template <typename T>
//	T& vector_ele_add(T& out, T& v1,T& v2)
//	{
//		return NInternal::vector_math_helper::ele_add(out,v1,v2,v2[0]);
//	}
//	//out = v1 - v2
//	template <typename T>
//	T& vector_ele_sub(T& out, T& v1,T& v2)
//	{
//		return NInternal::vector_math_helper::ele_sub(out,v1,v2,v2[0]);
//	}
//	//out = c + v
//	template <typename TC,typename T>
//	T& vector_coeff_add(T& out, const TC coff,T& v)
//	{
//		return NInternal::vector_math_helper::coff_add(out,coff,v,v[0]);
//	}
//	//out = c - v
//	template <typename TC,typename T>
//	T& vector_coeff_sub(T& out, const TC coff,T& t)
//	{
//		return NInternal::vector_math_helper::coff_sub(out,coff,t,t[0]);
//	}
//
//	template <typename TC,typename T>
//	T& vector_coeff_mul(T& out, const TC coff,T& v)
//	{
//		return NInternal::vector_math_helper::coff_mul(out,coff,v,(v[0]));
//	}
//	//out = coff * v
//	template <typename TC,typename T>
//	T& vector_coeff_div(T& out, const TC coff,T& v)
//	{
//		return NInternal::vector_math_helper::coff_div(out,coff,v,v[0]);
//	}
//
//	// out = v1 * v2
//	template <typename T>
//	T& vector_ele_mul(T& out, T& v1,T& v2)
//	{
//		return NInternal::vector_math_helper::ele_mul(out,v1,v2,v1[0]);
//	}
//	//out = t1 dot t2
//	template <typename T>
//	typename T::value_type& vector_dot_mul(T& out, T& t1,typename T::value_type& t2)
//	{
//		return NInternal::vector_math_helper::dot_mul(out,t1,t2,t1[0]);
//	}
//	// v1 dot v2
//	template <typename T>
//	typename T::atom_value_type& vector_dot_mul(typename T::atom_value_type& out,T& t1,T& t2)
//	{
//		return NInternal::vector_math_helper::dot_mul(out,t1,t2,t1[0]);
//	}
//	//out = mtx * v
//	template <typename T>
//	typename T::col_value_type& vector_mtx_mul_transpose(typename T::col_value_type& out,T& mtx,typename T::value_type& v)
//	{
//		for(i32 i = T::value_size - 1; i >= 0 ; i --)
//		{
//			vector_dot_mul((typename T::col_value_type::value_type&)(out[i]),mtx[i],v);
//		}
//		return out;
//	}
//	//out = v * mtx
//	template <typename T>
//	typename T::value_type& vector_mtx_mul(typename T::value_type& out,typename T::col_value_type& v,T& mtx)
//	{
//		for(i32 c = T::col_value_size - 1; c >= 0 ; c --)
//		{
//			NInternal::vector_math_helper::dot_mul(out[c],v[0],mtx[0][c]);
//			for(i32 r = T::value_size - 1; r > 0 ; r --)
//			{
//				NInternal::vector_math_helper::dot_mul_add((typename T::value_type::value_type&)(out[c]),v[r],mtx[r][c]);
//			}
//		}
//		return out;
//	}
//	//
//	//out = mtx * mtx
//	template <typename T>
//	typename T& vector_mtx_mul(T& out,T& m1,T& m2)
//	{
//		if(&out != &m1 &&
//			&out != &m2)
//		{
//			for(i32 r = T::row_value_size - 1; r >= 0 ; r --)
//			{
//				{
//					vector_mtx_mul(out[r],m1[r],m2);
//				}
//			}
//			return out;
//		}
//		else
//		{
//			T tmp;
//			for(i32 r = T::row_value_size - 1; r >= 0 ; r --)
//			{
//				{
//					vector_mtx_mul(tmp[r],m1[r],m2);
//				}
//			}
//			out = tmp;
//			return out;
//		}
//		return out;
//	}
//	template <typename T1,typename T2,typename T3>
//	typename T1& vector_mtx_mul(T1& out,T2& m1,T3& m2)
//	{
//		/*if(&out != &m1 &&
//			&out != &m2)*/
//		{
//			for(i32 r = T2::row_value_size - 1; r >= 0 ; r --)
//			{
//				{
//					vector_mtx_mul(out[r],m1[r],m2);
//				}
//			}
//			return out;
//		}
//		/*else
//		{
//			T1 tmp;
//			for(i32 r = T3::row_value_size - 1; r >= 0 ; r --)
//			{
//				{
//					vector_mtx_mul(tmp[r],m1[r],m2);
//				}
//			}
//			out = tmp;
//			return out;
//		}*/
//		return out;
//	}
//
//	/*template <typename T>
//	Void vector_print(char* arg,const T& t)
//	{
//		cout<<arg<<endl;
//		NInternal::print_helper(t);
//		cout<<endl;
//	}*/
//}

#endif // xVector_h__
